#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

class CopyBan
{
public:
	CopyBan()
	{}

private:
	CopyBan(const CopyBan&) = delete;
	CopyBan& operator=(const CopyBan&) = delete;
};

class HeapOnly
{
public:
	static HeapOnly* CreateObject()
	{
		return new HeapOnly;
	}
	HeapOnly(const HeapOnly& hp) = delete;//禁止拷贝
	HeapOnly& operator = (const HeapOnly& hp) = delete; // 禁止拷贝

private:
	HeapOnly() //构造函数
	{}
};

//int main()
//{
//	HeapOnly* php = HeapOnly::CreateObject(); // 只能在堆区创建对象
//	HeapOnly hp(*php);
//
//	delete php;
//	return 0;
//}


class StackOnly1
{
public:
	static StackOnly1 CreateObject()
	{
		StackOnly1 st;
		return st;
	}
	//StackOnly1(const StackOnly1& st) = delete; // 禁止拷贝
	//StackOnly1& operator = (const StackOnly1& st) = delete; // 禁止拷贝

private:
	StackOnly1()
	{}
};

class StackOnly2
{
public:
	StackOnly2() //构造函数
	{}
	void* operator new(size_t size) = delete; // 禁止调用new
	void operator delete(void* p) = delete; // 禁止调用delete
};

//int main()
//{
//	//StackOnly1 st1 = StackOnly1::CreateObject();
//	//static StackOnly1 st2;
//	//StackOnly1* st3 = new StackOnly1;
//	//static StackOnly1 copy_st2(st1);
//	//StackOnly1* copy_st3 = new StackOnly1(st1);
//
//	StackOnly2 st1;
//	static StackOnly2 st2;
//	//StackOnly2* st3 = new StackOnly2;
//
//	StackOnly1 st5 = StackOnly1::CreateObject();
//	static StackOnly1 st6 = StackOnly1::CreateObject();
//
//	return 0;
//}

//class NonInherit // 基类 C++98
//{
//private:
//	NonInherit() //基类构造函数私有
//	{}
//};
//
//class B : public NonInherit // 派生类
//{};

//class NonInherit final // 基类 C++11
//{
//private:
//
//};
//
//class B : public NonInherit // 派生类
//{};

//int main()
//{
//	return 0;
//}

//class Singleton // 饿汉模式
//{
//public:
//	static Singleton* GetInstance() // 获取单例对象接口
//	{
//		return &m_instance;
//	}
//
//private:
//	Singleton() // 构造函数私有化
//	{}
//	Singleton(const Singleton& s) = delete; // 禁止使用拷贝构造
//	Singleton& operator=(const Singleton& s) = delete; // 禁止使用赋值运算符重载
//
//	//保证单例对象在静态区且只有一个
//	static Singleton m_instance;//单例对象
//};
//
//Singleton Singleton::m_instance;//在程序入口之前就完成单例对象初始化
//
//int main()
//{
//	Singleton* s = Singleton::GetInstance();//获取单例对象
//
//	return 0;
//}

class Singleton // 懒汉模式
{
public:
	static Singleton* GetInstance()
	{
		// 如果单例对象没有创建则在堆区创建
		if (m_pInstance == nullptr)
		{
			m_pInstance = new Singleton;
		}

		return m_pInstance;
	}

private:
	Singleton() // 构造函数
	{}
	Singleton(const Singleton& s) = delete; // 禁止拷贝
	Singleton& operator=(const Singleton& s) = delete; // 禁止赋值

	// 静态单例对象指针
	static Singleton* m_pInstance; // 单例对象指针
};

Singleton* Singleton::m_pInstance = nullptr; // 初始化为空

int main()
{
	Singleton* ps = Singleton::GetInstance();//获取单例对象

	return 0;
}
